package com.party.core.service.system.impl;

import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.party.common.paging.Page;
import com.party.common.utils.LangUtils;
import com.party.common.utils.UUIDUtils;
import com.party.core.dao.read.system.SysPrivilegeReadDao;
import com.party.core.dao.write.system.SysPrivilegeWriteDao;
import com.party.core.model.BaseModel;
import com.party.core.model.system.SysPrivilege;
import com.party.core.model.system.SysRolePrivilege;
import com.party.core.service.system.ISysPrivilegeService;
import com.sun.istack.NotNull;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 权限接口实现
 *
 * @author Administrator
 *
 */
@Service
public class SysPrivilegeService implements ISysPrivilegeService {

	@Autowired
	SysPrivilegeReadDao sysPrivilegeReadDao;

	@Autowired
	SysPrivilegeWriteDao sysPrivilegeWriteDao;

	@Autowired
	SysRolePrivilegeService sysRolePrivilegeService;

	/**
	 * 系统权限插入
	 *
	 * @param sysPrivilege
	 *            系统权限
	 * @return 插入结果（true/false）
	 */
	@Override
	public String insert(SysPrivilege sysPrivilege) {
		sysPrivilege.setId(UUIDUtils.generateRandomUUID());
		sysPrivilege.setCreateDate(new Date());
		sysPrivilege.setUpdateDate(new Date());
		sysPrivilege.setDelFlag(BaseModel.DEL_FLAG_NORMAL);

		concatParentIds(sysPrivilege);
		boolean result = sysPrivilegeWriteDao.insert(sysPrivilege);
		if (result) {
			return sysPrivilege.getId();
		}
		return null;
	}

	/**
	 * 系统权限更新
	 *
	 * @param sysPrivilege
	 *            系统权限
	 * @return 更新结果（true/false）
	 */
	@Override
	public boolean update(SysPrivilege sysPrivilege) {
		sysPrivilege.setUpdateDate(new Date());
		concatParentIds(sysPrivilege);
		SysPrivilege dbPrivilege = get(sysPrivilege.getId());
		// 若修改了父节点 对应修改所有子节点的parentids
		if(null != dbPrivilege.getParentIds() && !dbPrivilege.getParentIds().equals(sysPrivilege.getParentIds())) {
			// 修改对应权限子菜单的parentids
			List<SysPrivilege> allPrivilegeChilds = getAllChilds(sysPrivilege);
			for (SysPrivilege child : allPrivilegeChilds) {
				String parentIds = child.getParentIds().replace(dbPrivilege.getParentIds(), sysPrivilege.getParentIds());
				child.setParentIds(parentIds);
				sysPrivilegeWriteDao.update(child);
			}
		}
		return sysPrivilegeWriteDao.update(sysPrivilege);
	}

	public SysPrivilege concatParentIds(SysPrivilege sysPrivilege) {
		if (null != sysPrivilege.getParentId()) {
			SysPrivilege parent = sysPrivilegeReadDao.get(sysPrivilege.getParentId());
			String parentIds = sysPrivilege.getParentId();
			if (null != parent && null != parent.getParentId()) {
				parentIds = parent.getParentIds() + parentIds + "," ;
			}else{
				if(!Strings.isNullOrEmpty(parentIds)){
					parentIds+=",";
				}
			}
			sysPrivilege.setParentIds(parentIds);
			return parent;
		}
		return null;
	}
	public List<SysPrivilege> getAllChilds(SysPrivilege privilege){
		if(!Strings.isNullOrEmpty(privilege.getId())){
			SysPrivilege search = new SysPrivilege();
			search.setParentIds(privilege.getId());
			return listPage(search, null);
		}
		return null;
	}

	@Override
	public List<SysPrivilege> webListPage(SysPrivilege sysPrivilege, Page page) {
		return sysPrivilegeReadDao.webListPage(sysPrivilege, page);
	}

	@Override
	public List<SysPrivilege> getRootList() {
		return sysPrivilegeReadDao.getRootList();
	}

	/**
	 * 系统权限删除
	 *
	 * @param id
	 *            实体主键
	 * @return 删除结果（true/false）
	 */
	@Override
	public boolean deleteLogic(@NotNull String id) {
		if (Strings.isNullOrEmpty(id)) {
			return false;
		}
		return sysPrivilegeWriteDao.deleteLogic(id);
	}

	/**
	 * 系统权限物理删除
	 *
	 * @param id
	 *            实体主键
	 * @return 删除结果（true/false）
	 */
	@Override
	public boolean delete(@NotNull String id) {
		// 删除子节点
		SysPrivilege search = new SysPrivilege();
		search.setParentIds(id);
		List<SysPrivilege> sysPrivileges = sysPrivilegeReadDao.listPage(search, null);
		for(SysPrivilege privilege:sysPrivileges){
			sysPrivilegeWriteDao.delete(privilege.getId());
		}
		return sysPrivilegeWriteDao.delete(id);
	}

	/**
	 * 系统权限批量逻辑删除
	 *
	 * @param ids
	 *            主键集合
	 * @return 删除结果（true/false）
	 */
	@Override
	public boolean batchDeleteLogic(@NotNull Set<String> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return false;
		}
		return sysPrivilegeWriteDao.batchDeleteLogic(ids);
	}

	/**
	 * 系统资源批量物理删除
	 *
	 * @param ids
	 *            主键集合
	 * @return 删除结果（true/false）
	 */
	@Override
	public boolean batchDelete(@NotNull Set<String> ids) {
		if (CollectionUtils.isEmpty(ids)) {
			return false;
		}
		return sysPrivilegeWriteDao.batchDelete(ids);
	}

	/**
	 * 根据主键获取系统资源
	 *
	 * @param id
	 *            主键
	 * @return 系统资源
	 */
	@Override
	public SysPrivilege get(String id) {
		return sysPrivilegeReadDao.get(id);
	}

	/**
	 * 分页查询系统资源
	 *
	 * @param sysPrivilege
	 *            系统资源
	 * @param page
	 *            分页信息
	 * @return 系统资源列表
	 */
	@Override
	public List<SysPrivilege> listPage(SysPrivilege sysPrivilege, Page page) {
		return sysPrivilegeReadDao.listPage(sysPrivilege, page);
	}

	/**
	 * 查询所有系统资源
	 *
	 * @param sysPrivilege
	 *            系统资源
	 * @return 系统资源列表
	 */
	@Override
	public List<SysPrivilege> list(SysPrivilege sysPrivilege) {
		return sysPrivilegeReadDao.listPage(sysPrivilege, null);
	}


	/**
	 * 根据父编号查询
	 * @param parentId 父编号
	 * @return 权限列表
	 */
	@Override
	public List<SysPrivilege> findByParent(String parentId) {
		SysPrivilege sysPrivilege = new SysPrivilege();
		sysPrivilege.setParentId(parentId);
		return this.list(sysPrivilege);
	}

	/**
	 * 批量查询系统资源
	 *
	 * @param ids
	 *            主键集合
	 * @param sysPrivilege
	 *            系统资源
	 * @param page
	 *            分页信息
	 * @return 系统资源列表
	 */
	@Override
	public List<SysPrivilege> batchList(@NotNull Set<String> ids, SysPrivilege sysPrivilege, Page page) {
		if (CollectionUtils.isEmpty(ids)) {
			return Collections.EMPTY_LIST;
		}
		return sysPrivilegeReadDao.batchList(ids, new HashedMap(), page);
	}

	/**
	 * 查看会员权限
	 * @param memberId 会员编号
	 * @return 权限集合
	 */
	@Override
	public List<SysPrivilege> findByMemberId(String memberId) {
		return sysPrivilegeReadDao.findByMemberId(memberId);
	}

	/**
	 * 根据角色查询权限
	 * @param roles 角色集合
	 * @return 权限集合
	 */
	@Override
	public List<SysPrivilege> findByRoles(Set<String> roles) {
		return sysPrivilegeReadDao.findByRoles(roles);
	}

	/**
	 * 提取资源代码
	 * @param privileges 资源集合
	 * @return 代码集合
	 */
	@Override
	public Set<String> extractCode(List<SysPrivilege> privileges) {
		Set<String> set = Sets.newHashSet();
		for (SysPrivilege privilege : privileges){
			set.add(privilege.getPermission());
		}
		return set;
	}

	@Override
	public List<SysPrivilege> findByRoleId(String roleId) {
		List<SysRolePrivilege> rolePrivileges = sysRolePrivilegeService.findByRoleId(roleId);
		List<String> privileges = LangUtils.transform(rolePrivileges, input -> input.getPrivilegeId());
		if (CollectionUtils.isEmpty(privileges)) {
			return Collections.EMPTY_LIST;
		}
		List<SysPrivilege> menuList = sysPrivilegeReadDao.batchList(new HashSet<>(privileges), null, null);
		return menuList;
	}
}
